home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS11.ADF / C / ps.c < prev    next >
C/C++ Source or Header  |  1986-08-05  |  7KB  |  219 lines

  1. #include        <stdio.h>
  2. #include        <libraries/dos.h>
  3. #include        <libraries/dosextens.h>
  4. #include        <exec/memory.h>
  5. #include        <exec/tasks.h>
  6.  
  7. /*
  8.  * P S :        Like the UN*X command of the same name, this reports on
  9.  *              running processes in the system. The current version only
  10.  *              reports CLI processes, so you don't see the filesystem
  11.  *              tasks. Written because I got tired of seeing the question
  12.  *              marks that status spits out at every opportunity.
  13.  *              This will build OK with 16 bit integers.
  14.  *
  15.  * Usage:       ps [-f]
  16.  *
  17.  * Author:      Dewi Williams ..!ihnp4!druca!dewi
  18.  * Status:      Public domain.
  19.  */
  20.      
  21. /* Defines */
  22.  
  23. /* Change typeless BCPL BPTR to typed C (for struct pointers). Don't
  24.  * use this define on an APTR, that's only a badly disguised void *.
  25.  */
  26. #define BPTR_TO_C(strtag, var)  ((struct strtag *)(BADDR( (ULONG) var)))
  27.  
  28. /* Use AmigaDOS i/o to keep executable size down */
  29. #define WSTR(s)         (void)Write(OutLock, s, (long)strlen(s))
  30. #define WCHR(s)         (void)Write(OutLock, s, 1L)     /* char w/ d. quotes */
  31.  
  32. #define TO_ASC(n)       ((n) + '0')             /* make it printable! */
  33.  
  34. /* Casting conveniences */
  35. #define PROC(task)              ((struct Process *)task)
  36. #define ROOTNODE                ((struct RootNode *)DOSBase->dl_Root)
  37. #define CLI(proc)               (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
  38.  
  39. /* Externs */
  40. extern struct DosLibrary *DOSBase;      /* dos library base pointer */
  41. extern struct FileLock   *Output();     /* get output file handle */
  42.  
  43. /* Globals */
  44. static struct FileLock   *OutLock;      /* used by WSTR define */
  45. static int               fullopt = 0;   /* set by -f command line flag */
  46.  
  47. main(argc, argv)
  48. int     argc;
  49. char    **argv;
  50. {
  51.         register ULONG   *tt;           /* References TaskArray         */
  52.         register int     count;         /* loop variable                */
  53.         register UBYTE   *port;         /* msgport & ptr arith          */
  54.         register struct Task *task;     /* EXEC descriptor              */
  55.         char             strbuf[256];   /* scratch for btocstr()        */
  56.         char             *btocstr();    /* BCPL BSTR to ASCIIZ          */
  57.         void             disp_hdr();    /* display ps header            */
  58.         void             display();     /* display data for one process */
  59.  
  60.         OutLock = Output();             /* initialize output handle     */
  61.  
  62.         if (argc > 1 && strcmp(argv[1], "-f") == 0) fullopt = 1;
  63.  
  64.         tt = (unsigned long *)(BADDR(ROOTNODE->rn_TaskArray));
  65.  
  66.         if (fullopt) disp_hdr();
  67.  
  68.         Forbid();               /* need linked list consistency */
  69.      
  70.         /* Loop through the data for the CLI processes. */
  71.         for (count = 1; count <= (int)tt[0] ; count++) {/* or just assume 20?*/
  72.                 if (tt[count] == 0) continue;           /* nobody home */
  73.  
  74.                 /* Start by pulling out MsgPort addresses from the TaskArray
  75.                  * area. By making unwarranted assumptions about the layout
  76.                  * of Process and Task structures, we can derive these
  77.                  * descriptors. Every task has an associated process, since
  78.                  * this loop drives off a CLI data area.
  79.                  */
  80.  
  81.                 port = (UBYTE *)tt[count];
  82.                 task = (struct Task *)(port - sizeof(struct Task));
  83.  
  84.                 /* Sanity check just in case */
  85.                 if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == NULL)
  86.                         continue;               /* or complain? */
  87.  
  88.                 /* Pass the C string version of the command name to
  89.                  * the display routine.
  90.                  */
  91.                 display(count, task->tc_Node.ln_Name,
  92.                         btocstr(CLI(PROC(task))->cli_CommandName, strbuf),
  93.                         task->tc_Node.ln_Pri);
  94.         }
  95.         Permit();               /* outside critical region */
  96.         exit(0);
  97. }
  98.  
  99. /*
  100.  * Convert a BCPL string to a C string. To avoid scrogging in-memory
  101.  * stuff, it copies it first. Your data area better be big enough!
  102.  */
  103.  
  104. char *
  105. btocstr(b, buf)
  106. ULONG   b;
  107. char    *buf;
  108. {
  109.         register char   *s;
  110.  
  111.         s = (char *)BADDR(b);   /* Shift & get length-prefixed str */
  112.         (void)movmem(s +1, buf, s[0]);  /* a.k.a memcpy */
  113.         buf[s[0]] = '\0';
  114.         return buf;
  115. }
  116.  
  117. /*
  118.  * Display the header for the output.
  119.  */
  120.  
  121. void
  122. disp_hdr()
  123. {
  124.         WSTR("Process #  CLI Type         Command Name         Priority\n");
  125. }
  126.  
  127. /*
  128.  * Display the information for a particular CLI process. Keep the format
  129.  * string in sync with that of disp_hdr().
  130.  */
  131.  
  132. void
  133. display(tnum, type, name, pri)
  134. int     tnum;           /* CLI process number */
  135. char    *type;          /* Initial, Background or New CLI */
  136. char    *name;          /* Command name if CLI's running one */
  137. int     pri;            /* priority of CLI & command */
  138. {
  139.         char            *psitoa();
  140.         char            buf[80];
  141.         char            *ext_len();
  142.         register char   *p = buf;
  143.  
  144.         if (*name == '\0') name = "<Cli>";      /* Null, nothing loaded */
  145.  
  146.         if (fullopt) {
  147.                 p = ext_len(psitoa(tnum, p), 11);
  148.                 strcpy(p, type);
  149.                 p = ext_len(p, 17);
  150.                 strcpy(p, name);
  151.                 p = ext_len(p, 21);
  152.                 (void)psitoa(pri, p);
  153.         } else {
  154.                 p = ext_len(psitoa(tnum, p), 2);
  155.                 *p++ = ':';
  156.                 *p++ = ' ';
  157.                 strcpy(p, name);
  158.         }
  159.  
  160.         WSTR(buf);
  161.         WCHR("\n");
  162. }
  163.  
  164. /*
  165.  * Everything after here is a hack to avoid dragging in printf.
  166.  * ------------------------------------------------------------
  167.  */
  168.      
  169. /*
  170.  * Limited itoa style function. Don't use it anywhere else! Used to keep
  171.  * things small & avoid printf. Has a very limited range (3 digits +/- sign).
  172.  * This hack avoids having to do the recursion & reverse of K&R itoa.
  173.  */
  174.      
  175. char *
  176. psitoa(num, into)
  177. int     num;                            /* number to convert  */
  178. char    *into;                          /* write it into here */
  179. {
  180.         register char   *p = into;
  181.      
  182.         if (num < 0) {
  183.                 *p++ = '-';
  184.                 num = -num;
  185.         }
  186.         if (num > 99) {
  187.                 *p++ = TO_ASC(num/100);
  188.                 *p++ = TO_ASC((num%100)/10);
  189.                 *p++ = TO_ASC(num%10);
  190.         } else if (num > 9) {
  191.                 *p++ = TO_ASC(num/10);
  192.                 *p++ = TO_ASC(num%10);
  193.         } else
  194.                 *p++ = TO_ASC(num);
  195.  
  196.         *p = '\0';                      /* end of the string */
  197.         return into;
  198. }
  199.  
  200. /*
  201.  * Extend to length. Assumes strlen(s) never greater than len.
  202.  */
  203.  
  204. char *
  205. ext_len(s, len)
  206. char    *s;                     /* must be large enough for extension to len */
  207. int     len;
  208. {
  209.         register int    leftover;
  210.         register int    slen = strlen(s);
  211.         register char   *p = s + slen;
  212.      
  213.         for(leftover = len - slen; leftover > 0; leftover--)
  214.                 *p++ = ' ';
  215.  
  216.         *p = '\0';              /* null terminate */
  217.         return p;               /* return loc after string */
  218. }
  219.